//
//  rgk.h
//  RetroGameKit
//
//  Created by Michael Burns on 10/27/13.
//  Copyright (c) 2013 Michael Burns. All rights reserved.
//
//  RetroGameKit is a tiny wrapper for SDL2 that minimalizes
//  the work needed to set up a 2D game window, load images,
//  catch input events, and all that fun stuff. It's best
//  suited for rapidly developing simple 2D games.

#ifndef RetroGameKit_rgk_h
#define RetroGameKit_rgk_h

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <SDL2_mixer/SDL_mixer.h>

/*
 * RGKDisplay
 * setup a display.
 */
typedef struct {
    SDL_Window *window;
    SDL_Renderer *renderer;
    int w;
    int h;
    double zoomFactor;
} RGKDisplay;

int RGKDisplayInit(int screen_width, int screen_height, const char *title, double zoomFactor);
void RGKDisplayQuit();
void RGKDisplayClear(int r, int g, int b);
void RGKDisplayPresent();

void RGKCapFramerate(double fps);

/*
 * RGKInput
 * catch input.
 */

typedef enum {
    RGK_KEYDOWN         = 1,
    RGK_KEYUP           = 2,
    RGK_MOUSEBUTTONDOWN = 3,
    RGK_MOUSEBUTTONUP   = 4,
    RGK_MOUSEMOTION     = 5,
    RGK_QUIT            = 6,
} RGKEventType;

// Note: incomplete, and some is unnecessary for my purposes.
typedef enum {
    RGKK_ESCAPE    = SDL_SCANCODE_ESCAPE,
    RGKK_RETURN    = SDL_SCANCODE_RETURN,
    RGKK_SPACE     = SDL_SCANCODE_SPACE,
    RGKK_BACKSPACE = SDL_SCANCODE_BACKSPACE,
    RGKK_LSHIFT    = SDL_SCANCODE_LSHIFT,
    RGKK_RSHIFT    = SDL_SCANCODE_RSHIFT,
    RGKK_LCTRL     = SDL_SCANCODE_LCTRL,
    RGKK_RCTRL     = SDL_SCANCODE_RCTRL,
    RGKK_UP        = SDL_SCANCODE_UP,
    RGKK_DOWN      = SDL_SCANCODE_DOWN,
    RGKK_LEFT      = SDL_SCANCODE_LEFT,
    RGKK_RIGHT     = SDL_SCANCODE_RIGHT,
    RGKK_0         = SDL_SCANCODE_0,
    RGKK_1         = SDL_SCANCODE_1,
    RGKK_2         = SDL_SCANCODE_2,
    RGKK_3         = SDL_SCANCODE_3,
    RGKK_4         = SDL_SCANCODE_4,
    RGKK_5         = SDL_SCANCODE_5,
    RGKK_6         = SDL_SCANCODE_6,
    RGKK_7         = SDL_SCANCODE_7,
    RGKK_8         = SDL_SCANCODE_8,
    RGKK_9         = SDL_SCANCODE_9,
    RGKK_A         = SDL_SCANCODE_A,
    RGKK_B         = SDL_SCANCODE_B,
    RGKK_C         = SDL_SCANCODE_C,
    RGKK_D         = SDL_SCANCODE_D,
    RGKK_E         = SDL_SCANCODE_E,
    RGKK_F         = SDL_SCANCODE_F,
    RGKK_G         = SDL_SCANCODE_G,
    RGKK_H         = SDL_SCANCODE_H,
    RGKK_I         = SDL_SCANCODE_I,
    RGKK_J         = SDL_SCANCODE_J,
    RGKK_K         = SDL_SCANCODE_K,
    RGKK_L         = SDL_SCANCODE_L,
    RGKK_M         = SDL_SCANCODE_M,
    RGKK_N         = SDL_SCANCODE_N,
    RGKK_O         = SDL_SCANCODE_O,
    RGKK_P         = SDL_SCANCODE_P,
    RGKK_Q         = SDL_SCANCODE_Q,
    RGKK_R         = SDL_SCANCODE_R,
    RGKK_S         = SDL_SCANCODE_S,
    RGKK_T         = SDL_SCANCODE_T,
    RGKK_U         = SDL_SCANCODE_U,
    RGKK_V         = SDL_SCANCODE_V,
    RGKK_W         = SDL_SCANCODE_W,
    RGKK_X         = SDL_SCANCODE_X,
    RGKK_Y         = SDL_SCANCODE_Y,
    RGKK_Z         = SDL_SCANCODE_Z,
} RGKKey;

typedef struct {
    int type;
    int key;
    int x;
    int y;
    int button;
} RGKEvent;

int RGKPollEvent(RGKEvent *e);
const Uint8 *RGKGetKeyboardState(int *numkeys);

/* 
 * RGKRect
 * rectangle!
 */

typedef struct {
    double x;
    double y;
    double w;
    double h;
} RGKRect;

RGKRect RGKRectMake(double x, double y, double w, double h);
int RGKRectIntersects(RGKRect rect1, RGKRect rect2);
RGKRect RGKRectMove(RGKRect r, double dx, double dy);

/*
 * RGKImage
 * load and draw images.
 */
typedef struct {
    SDL_Texture *tex;
    SDL_Rect dst;
    SDL_Rect src;
    int w;
    int h;
} RGKImage;

RGKImage *RGKImageLoad(const char *filename);
void RGKImageFree(RGKImage *image);
void RGKImageDraw(RGKImage *image, RGKRect dest, RGKRect src,
                  double angle, int flip_x, int flip_y);

/*
 * RGKSound
 * load and play sounds.
 */
typedef struct {
    Mix_Chunk *chunk;
} RGKSound;

RGKSound *RGKSoundLoad(const char *filename);
void RGKSoundFree(RGKSound *sound);
void RGKSoundPlay(RGKSound *sound, int loops);
void RGKSoundSetVolume(RGKSound *sound, double volume);

/*
 * RGKMusic
 * load and play music.
 */
typedef struct {
    Mix_Music *music;
} RGKMusic;

RGKMusic *RGKMusicLoad(const char *filename);
void RGKMusicFree(RGKMusic *music);
void RGKMusicPlay(RGKMusic *music, int loops);
void RGKMusicStop();
void RGKMusicPause();
void RGKMusicResume();
void RGKMusicSetVolume(double volume);

#endif
